Initializes this. Adds item to this and connects to the signals emitted by item.
Alias letting you know what this is a collection of.
The key_type is alias'd as the type since it looked better than having typeof(T.key) everywhere.
Adds item to this and connects to the signals emitted by item. Notifies that the length of this has changed.
Checks if item is in the collection.
Gets the length of the collection.
Changes this to not contain changes and also marks all the items as saved. Should only be used after a save.
Notifies this which property changed and sets containsChanges to true. This also emits a signal with the property name that changed and the key to it in this collection.
Allows you to use this in a foreach loop.
The InExpression yields a pointer to the value if the key is in the associative array, or null if not.
Forwards all methods not specified by this abstract class to the private associative array.
Gets the approriate T. You can either use an item that equals the item you want back, a key of the item you want back or parameters that can make the key for the item you want back.
This just calls $(SRCTAG KeyedCollection.add).
Removes an item from this and disconnects the signals. Notifies that the length of this has changed by emitting "remove".
Checks if the item has any conflicting exclusion constraints.
Checks if the item has any conflicting exclusion constraints.
Checks if the item has any conflicting unique constraints. This is more extensive than $(SRCTAG KeyedCollection.contains).
The signal used to emit changes that occur in this.
Read-only property telling if this contains changes.
Write-only property to enforce the constraints. By default this is (Enforce.check | Enforce.unique | Enforce.foreignKey | Enforce.exclusion) but you may set it to 0 if you have a lot of initial data and already trust that it does not violate any constraints.
1 // singular class this holds all of the columns 2 class Candy 3 { 4 private: 5 string _name; 6 int _ranking; 7 public: 8 // marking name as part of the primary key 9 @PrimaryKeyColumn @NotNull 10 @property string name() const nothrow pure @safe @nogc 11 { 12 return _name; 13 } 14 @property void name(string value) 15 { 16 setter(_name, value); 17 } 18 @property int ranking() const nothrow pure @safe @nogc 19 { 20 return _ranking; 21 } 22 // making sure that ranking will always be above 0 23 @CheckConstraint!(a => a > 0, "chk_Candys_ranking") 24 @property void ranking(int value) 25 { 26 setter(_ranking, value); 27 } 28 29 this(string name, int ranking) 30 { 31 this._name = name; 32 this._ranking = ranking; 33 // need to initialize the keyed item 34 initializeKeyedItem(); 35 } 36 Candy dup() const 37 { 38 return new Candy(this._name, this._ranking); 39 } 40 // the default is to make the primary key into the clustered index 41 // which allows you to search based on the primary key 42 mixin KeyedItem!(); 43 } 44 45 // plural class 46 // I am using an alias since BaseKeyedCollection 47 // takes care of everything I want to do for this example in one line. 48 alias Candies = BaseKeyedCollection!(Candy); 49 50 // Candies is a collection of Candy 51 static assert(is(Candies.collectionof == Candy)); 52 53 // source: 54 // http://www.bloomberg.com/ss/09/10/1021_americas_25_top_selling_candies/ 55 // should be Milky not Milkey, this is wrong on purpose 56 auto milkyWay = new Candy("Milkey Way", 18); 57 auto snickers = new Candy("Snickers", 4); 58 auto reesesPBCups = new Candy("Reese's Peanut Butter Cups", 2); 59 60 auto mars = new Candies([milkyWay, snickers]); 61 assert(mars.length == 2); 62 assert(!mars.containsChanges); 63 64 auto hershey = new Candies(reesesPBCups); 65 assert(hershey.length == 1); 66 67 // use the class as an index and confirm it returns the correct value 68 assert(mars[milkyWay] is milkyWay); 69 // use the primary key as an index 70 auto pk = Candy.PrimaryKey("Milkey Way"); 71 assert(pk.name == milkyWay.name); 72 assert(mars[pk] is milkyWay); 73 // use the contents of the primary key as an index 74 assert(mars["Milkey Way"] is milkyWay); 75 76 // milky way is in mars 77 assert(mars.contains(pk)); 78 // reesesPBCups is not in mars 79 assert(!mars.contains(reesesPBCups)); 80 81 // now we change the name to be correct 82 mars[pk].name = "Milky Way"; // remember pk is primary key for milky way 83 84 // since we changed milky way's name, mars contains changes 85 assert(mars.containsChanges); 86 87 // since we had name in pk spelled incorrectly 88 // and changed it, the primary key in mars has 89 // updated so Milkey Way is no longer in it but 90 // Milky Way is. 91 assert(!mars.contains("Milkey Way")); 92 assert(mars.contains("Milky Way")); 93 94 // looping over mars we make sure the key can be used to get 95 // the correct value. 96 foreach(name_pk, candy; mars) 97 { 98 assert(mars[name_pk] == candy); 99 } 100 101 // trying to add another candy with the same name will 102 // result in a unique constraint violation even if the ranking is different 103 auto milkyWay2 = new Candy("Milky Way", 16); 104 assert(milkyWay.name == milkyWay2.name); 105 assert(milkyWay.ranking != milkyWay2.ranking); 106 import std.exception : assertThrown; 107 assertThrown!(UniqueConstraintException)(mars ~= milkyWay2); 108 109 // ranking has a check constraint saying ranking always must be greater 110 // than 0. setting it to -1 resolves in a CheckConstraintException. 111 assertThrown!(CheckConstraintException)(mars["Milky Way"].ranking = -1); 112 // Since name is part of the primary key we must mark it with NotNull 113 // trying to set this to null will result in a CheckConstraintException. 114 assertThrown!(CheckConstraintException)(mars["Milky Way"].name = null); 115 116 // violatesUniqueConstraints will tell you which unique constraint 117 // is violated if any 118 string violatedConstraint; 119 assert(mars.violatesUniqueConstraints(milkyWay2, violatedConstraint)); 120 assert(violatedConstraint !is null && violatedConstraint == "PrimaryKey"); 121 122 // removing milky way from mars 123 mars.remove(milkyWay); 124 // this means milkyWay2 is no longer a duplicate 125 assert(!mars.violatesUniqueConstraints(milkyWay2, violatedConstraint)); 126 assert(violatedConstraint is null);
Turns the inheriting class into a keyed collection. The key is based on the singular class' clustered index. The requirements (except for dup) are taken care of when you include the keyeditem in the T class.
T should represent a single row in the database. Use this when T has foreign keys.